package ru.fadeev.crammer.ui;

import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JTextField;


/**
 * TransTextField extends JTextField so it can accept and show transcription
 * characters.
 * @author Konstantin Fadeyev
 *
 */
public class TransTextField extends JTextField {
    protected char[] transMapKeys = {
    		'a',
    		'q',
    		'x',
    		'i',
    		'e',
    		'o',
    		'u',
    		
    		'R',
    		'Q',
    		'I',
    		'O',
    		'U',
    		
    		'H',
    		'y',
    		'Y',
    		'E',
    		'W',
    		'X',
    		'F',
    		'A',

    		'b',
    		'd',
    		'f',
    		'g',
    		'h',
    		'j',
    		'k',
    		'l',
    		'm',
    		'n',
    		'p',
    		'r',
    		's',
    		't',
    		'v',
    		'w',
    		'z',
    		
    		'G',
    		'J',
    		'S',
    		'C',
    		'T',
    		'D',
    		'N',
    		'\'',
    		'\"'
    		};  		
    protected char[][] transMapValues = {
    		{'\u028c'},
    		{'\u0259'},
    		{'\u00e6'},
    		{'\u026a'},
    		{'e'},
    		{'\u0252'},
    		{'\u028a'},
    		
    		{'\u0251', '\u02d0'}, 		
    		{'\u025c', '\u02d0'}, 		
    		{'i', '\u02d0'}, 		
    		{'\u0254', '\u02d0'}, 		
    		{'u', '\u02d0'}, 	
    		
    		{'a', '\u028a'}, 		
    		{'a', '\u026a'}, 		
    		{'\u0254', '\u026a'}, 		
    		{'e', '\u026a'}, 		
    		{'\u0259', '\u028a'}, 		
    		{'e', '\u0259'}, 	
    		{'\u026a', '\u0259'}, 		
    		{'\u028a', '\u0259'}, 		

    		{'b'},
    		{'d'},
    		{'f'},
    		{'g'},
    		{'h'},
    		{'j'},
    		{'k'},
    		{'l'},
    		{'m'},
    		{'n'},
    		{'p'},
    		{'r'},
    		{'s'},
    		{'t'},
    		{'v'},
    		{'w'},
    		{'z'},

    		{'\u0292'},
    		{'\u02a4'},
    		{'\u0283'},
    		{'\u02a7'},
    		{'\u03b8'},
    		{'\u00f0'},
    		{'\u014b'},
    		{'\u02c8'},
    		{'\u02cc'},
    };
    
    public TransTextField() {
    	super();
    	Font defaultFont = getFont();
    	setFont(new Font("LucidaSans", 
    			defaultFont.getStyle(), defaultFont.getSize()));
    	addKeyListener(
    			new KeyAdapter() {
    				public void keyTyped(KeyEvent e) {
    					char key = e.getKeyChar();
    					
    					for(int i = 0; i < transMapKeys.length; i++) {
    						if(key == transMapKeys[i]) {
    							if(transMapValues[i].length==1) {
    								e.setKeyChar(transMapValues[i][0]);
    							} else {
    								e.setKeyChar(transMapValues[i][1]);
    								String s = getText();
    								int index = getCaretPosition();
        							setText(s.substring(0, index) + transMapValues[i][0] +
        									s.substring(index));
        							setCaretPosition(index+1);
    							}
    							return;
    						}
    					}
    					e.consume();
    				}
    				
    				public void keyPressed(KeyEvent e) {
    					if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
    						if(getSelectionStart() != getSelectionEnd()) {
    							return;
    						}
    						int index = getCaretPosition();
    						if(index > 1) {
    							if( !validString(getText().substring(0, index - 1), true) ||
    									!validString(getText().substring(index), false)) {
    								String s = getText();
        							setText(s.substring(0, index - 2) + 
        									s.substring(index-1));
        							setCaretPosition(index-1);
    							}
    							return;    							
    						}
    					}
    					if(e.getKeyCode() == KeyEvent.VK_DELETE) {
    						if(getSelectionStart() != getSelectionEnd()) {
    							return;
    						}
    						int index = getCaretPosition();
    						if(index + 1 < getText().length()) {
    							if( !validString(getText().substring(0, index ), true) ||
    									!validString(getText().substring(index + 1), false)) {
    								String s = getText();
        							setText(s.substring(0, index) + 
        									s.substring(index+1));
    								setCaretPosition(index);
    							}
    							return;
    						}
    					}
    					if(e.getKeyCode() == KeyEvent.VK_LEFT) {
    						int index = getCaretPosition();
    						if(index > 1) {
    							if( !validString(getText().substring(0, index-1), true) ||
    									!validString(getText().substring(index-1), false)) {
    								setCaretPosition(index-1);				
    							}
    							return;
    						}
    					}
    					if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
    						int index = getCaretPosition();
    						if(index + 1 < getText().length()) {
    							if( !validString(getText().substring(0, index+1), true) ||
    									!validString(getText().substring(index+1), false)) {
    								setCaretPosition(index+1);
        							return;
    							}
    						}
    					}

    				}
    			});
    	addMouseListener(
    		new MouseAdapter() {
    			public void mousePressed(MouseEvent e) {
    				int caret = getCaretPosition();
					if((caret > 0) && (caret < getText().length())) {
						if( !validString(getText().substring(0, caret), true) ||
								!validString(getText().substring(caret), false)) {
							setCaretPosition(caret-1);
							return;
						}
					}
    			}
    		}
    	);
    	addMouseMotionListener(
    			new MouseMotionAdapter() {
    				public void mouseDragged(MouseEvent e) {
    					int start = getSelectionStart();
    					int end = getSelectionEnd();
    					int caret = getCaretPosition();
    					if(start != end) {
							if((caret > 0) && (caret < getText().length())) {
								if( !validString(getText().substring(0, caret), true) ||
										!validString(getText().substring(caret), false)) {
									if(caret == start) {
    									moveCaretPosition(start - 1);
    								} else {
    									moveCaretPosition(end + 1);
    								}
								}
    						}
    					}
    				}
    			});
    }
    
    private boolean validString(String s, boolean right) {
    	int length = s.length();
    	if(length == 0) {
			return true;
		}
    	if(length > 1) {
			char char1 = right ? s.charAt(length - 2) : s.charAt(0);
			char char2 = right ? s.charAt(length - 1) : s.charAt(1);

			for(int i = 0; i < transMapValues.length; i++) {
				if(transMapValues[i].length==2) {
					if((transMapValues[i][0] == char1) && (transMapValues[i][1] == char2)) {
						if(length == 2) {
							return true;
						}
						boolean restIsValid = right ? 
								validString(s.substring(0, length - 2), right) :
								validString(s.substring(2, length), right);
						if(restIsValid) {
							return true;
						}
					}
				}
			}
    	} if(s.length() > 0){
			char char1 = right ? s.charAt(length - 1) : s.charAt(0);

			for(int i = 0; i < transMapValues.length; i++) {
				if(transMapValues[i].length == 1) {
					if(transMapValues[i][0] == char1) {
						if(length == 1) {
							return true;
						}
						boolean restIsValid = right ? 
								validString(s.substring(0, length - 1), right) :
								validString(s.substring(1, length), right);
						if(restIsValid) {
							return true;
						}
					}
				}
			}
    	} 
    	return false;
    }
}
